home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / language / embedded / m68k / cc68k.arc / OUTCODE.C < prev    next >
C/C++ Source or Header  |  1989-09-24  |  12KB  |  438 lines

  1. #include        "stdio.h"
  2. #include        "string.h"
  3. #include        "c.h"
  4. #include        "expr.h"
  5. #include        "gen.h"
  6. #include        "cglbdec.h"
  7.  
  8. /*
  9.  *    68000 C compiler
  10.  *
  11.  *    Copyright 1984, 1985, 1986 Matthew Brandt.
  12.  *  all commercial rights reserved.
  13.  *
  14.  *    This compiler is intended as an instructive tool for personal use. Any
  15.  *    use for profit without the written consent of the author is prohibited.
  16.  *
  17.  *    This compiler may be distributed freely for non-commercial use as long
  18.  *    as this notice stays intact. Please forward any enhancements or questions
  19.  *    to:
  20.  *
  21.  *        Matthew Brandt
  22.  *        Box 920337
  23.  *        Norcross, Ga 30092
  24.  */
  25.  
  26. /*      variable initialization         */
  27.  
  28. enum e_gt { nogen, bytegen, wordgen, longgen };
  29. enum e_sg { noseg, codeseg, dataseg };
  30.  
  31. int           gentype = nogen;
  32. int           curseg = noseg;
  33. int        outcol = 0;
  34.  
  35. struct oplst {
  36.         char    *s;
  37.         int     ov;
  38.         }       opl[] =
  39.         {       {"MOVE",op_move}, {"MOVE",op_moveq}, {"ADD",op_add},
  40.                 {"ADD",op_addi}, {"ADD",op_addq}, {"SUB",op_sub},
  41.                 {"SUB",op_subi}, {"SUB",op_subq}, {"AND",op_and},
  42.                 {"OR",op_or}, {"EOR",op_eor}, {"MULS",op_muls},
  43.                 {"DIVS",op_divs}, {"SWAP",op_swap}, {"BEQ",op_beq},
  44.                 {"BHI",op_bhi}, {"BHS",op_bhs}, {"BLO",op_blo},
  45.                 {"BLS",op_bls}, {"MULU",op_mulu}, {"DIVU",op_divu},
  46.                 {"BNE",op_bne}, {"BLT",op_blt}, {"BLE",op_ble},
  47.                 {"BGT",op_bgt}, {"BGE",op_bge}, {"NEG",op_neg},
  48.                 {"NOT",op_not}, {"CMP",op_cmp}, {"EXT",op_ext},
  49.                 {"JMP",op_jmp}, {"JSR",op_jsr}, {"RTS",op_rts},
  50.                 {"LEA",op_lea}, {"ASR",op_asr}, {"ASL",op_asl},
  51.                 {"CLR",op_clr}, {"LINK",op_link}, {"UNLK",op_unlk},
  52.                 {"BRA",op_bra}, {"MOVEM",op_movem}, {"PEA",op_pea},
  53.                 {"CMP",op_cmpi}, {"TST",op_tst}, {"DC",op_dc},
  54.                 {0,0} };
  55.  
  56.  putop(op)
  57. int     op;
  58. {       int     i;
  59.         i = 0;
  60.         while( opl[i].s )
  61.                 {
  62.                 if( opl[i].ov == op )
  63.                         {
  64.                         fprintf(output,"\t%s",opl[i].s);
  65.                         return;
  66.                         }
  67.                 ++i;
  68.                 }
  69.         printf("DIAG - illegal opcode.\n");
  70. }
  71.  
  72.  putconst(offset)
  73. /*
  74.  *      put a constant to the output file.
  75.  */
  76. struct enode    *offset;
  77. {
  78.    char su[80];
  79.  
  80.        switch( offset->nodetype )
  81.                 {
  82.                 case en_autocon:
  83.                 case en_icon:
  84.                         fprintf(output,"%d",offset->v.i);
  85.                         break;
  86.                 case en_labcon:
  87.             fprintf(output,"L_%d",offset->v.i);
  88.                         break;
  89.                 case en_nacon:
  90.                         strcpy(su,(char *)(offset->v.p[0]));    /* copy labels str */
  91.                         upcase(su);              /* Transform to upper */
  92.                         fprintf(output,"%s",su);
  93.                         break;
  94.                 case en_add:
  95.                         putconst(offset->v.p[0]);
  96.                         fprintf(output,"+");
  97.                         putconst(offset->v.p[1]);
  98.                         break;
  99.                 case en_sub:
  100.                         putconst(offset->v.p[0]);
  101.                         fprintf(output,"-");
  102.                         putconst(offset->v.p[1]);
  103.                         break;
  104.                 case en_uminus:
  105.                         fprintf(output,"-");
  106.                         putconst(offset->v.p[0]);
  107.                         break;
  108.                 default:
  109.                         printf("DIAG - illegal constant node.\n");
  110.                         break;
  111.                 }
  112. }
  113.  
  114.  putlen(l)
  115. /*
  116.  *      append the length field to an instruction.
  117.  */
  118. int     l;
  119. {       switch( l )
  120.                 {
  121.                 case 0:
  122.                         break;  /* no length field */
  123.                 case 1:
  124.                         fprintf(output,".B");
  125.                         break;
  126.                 case 2:
  127.                         fprintf(output,".W");
  128.                         break;
  129.                 case 4:
  130.                         fprintf(output,".L");
  131.                         break;
  132.                 default:
  133.                         printf("DIAG - illegal length field.\n");
  134.                         break;
  135.                 }
  136. }
  137.  
  138.  putamode(ap)
  139. /*
  140.  *      output a general addressing mode.
  141.  */
  142. struct amode    *ap;
  143. {       switch( ap->mode )
  144.                 {
  145.                 case am_immed:
  146.                         fprintf(output,"#");
  147.                 case am_direct:
  148.                         putconst(ap->offset);
  149.                         break;
  150.                 case am_areg:
  151.                         fprintf(output,"A%d",ap->preg);
  152.                         break;
  153.                 case am_dreg:
  154.                         fprintf(output,"D%d",ap->preg);
  155.                         break;
  156.                 case am_ind:
  157.                         fprintf(output,"(A%d)",ap->preg);
  158.                         break;
  159.                 case am_ainc:
  160.                         fprintf(output,"(A%d)+",ap->preg);
  161.                         break;
  162.                 case am_adec:
  163.                         fprintf(output,"-(A%d)",ap->preg);
  164.                         break;
  165.                 case am_indx:
  166.                         putconst(ap->offset);
  167.                         fprintf(output,"(A%d)",ap->preg);
  168.                         break;
  169.                 case am_xpc:
  170.                         putconst(ap->offset);
  171.                         fprintf(output,"(D%d,PC)",ap->preg);
  172.                         break;
  173.                 case am_indx2:
  174.                         putconst(ap->offset);
  175.                         fprintf(output,"(A%d,D%d.L)",ap->preg,ap->sreg);
  176.                         break;
  177.                 case am_indx3:
  178.                         putconst(ap->offset);
  179.                         fprintf(output,"(A%d,A%d.L)",ap->preg,ap->sreg);
  180.                         break;
  181.                 case am_mask:
  182.                         put_mask((int)(ap->offset));
  183.                         break;
  184.                 default:
  185.                         printf("DIAG - illegal address mode.\n");
  186.                         break;
  187.                 }
  188. }
  189.  
  190.  put_code(op,len,aps,apd)
  191. /*
  192.  *      output a generic instruction.
  193.  */
  194. struct amode    *aps, *apd;
  195. int             op, len;
  196. {       if( op == op_dc )
  197.         {
  198.         switch( len )
  199.             {
  200.             case 1: fprintf(output,"\tDC.B"); break;
  201.             case 2: fprintf(output,"\tDC.W"); break;
  202.             case 4: fprintf(output,"\tDC.L"); break;
  203.             }
  204.         }
  205.     else
  206.         {
  207.         putop(op);
  208.             putlen(len);
  209.         }
  210.         if( aps != 0 )
  211.                 {
  212.                 fprintf(output,"\t");
  213.         putamode(aps);
  214.                 if( apd != 0 )
  215.                         {
  216.                         fprintf(output,",");
  217.                            putamode(apd);
  218.                         }
  219.                 }
  220.         fprintf(output,"\n");
  221. }
  222.  
  223.  put_mask(mask)
  224. /*
  225.  *      generate a register mask for restore and save.
  226.  */
  227. int     mask;
  228. {       int     i;
  229.         int     notfirst;
  230. /*        fprintf(output,"#$%04X",mask);    */
  231.  
  232.         notfirst = 0;
  233.         for(i=0; i< 16; i++)
  234.         {  if((mask & (1 << (15-i))) != 0)
  235.            { if( notfirst ) fprintf(output,"/");
  236.              notfirst=1;
  237.              putreg(i);
  238.            }
  239.         }
  240.  
  241.  
  242. }
  243.  
  244.  putreg(r)
  245. /*
  246.  *      generate a register name from a tempref number.
  247.  */
  248. int     r;
  249. {       if( r < 8 )
  250.                 fprintf(output,"D%d",r);
  251.         else
  252.                 fprintf(output,"A%d",r - 8);
  253. }
  254.  
  255.  gen_strlab(s)
  256. /*
  257.  *      generate a named label.
  258.  */
  259. char    *s;
  260. {
  261.   char su[80];
  262.   strcpy(su,s);            /* Copy the label... */
  263.   upcase(su);            /* Convert to upper case */
  264.        fprintf(output,"%s:\n",su);
  265. }
  266.  
  267.  put_label(lab)
  268. /*
  269.  *      output a compiler generated label.
  270.  */
  271. int     lab;
  272. {       fprintf(output,"L_%d:\n",lab);
  273. }
  274.  
  275. int genbyte(val)
  276. int     val;
  277. {       if( gentype == bytegen && outcol < 60) {
  278.                 fprintf(output,",%d",val & 0x00ff);
  279.                 outcol += 4;
  280.                 }
  281.         else    {
  282.                 nl();
  283.                 fprintf(output,"\tDC.B\t%d",val & 0x00ff);
  284.                 gentype = bytegen;
  285.                 outcol = 19;
  286.                 }
  287.         return 1;               /* 1 byte per byte      */
  288. }
  289.  
  290. int genword(val)
  291. int     val;
  292. {       if( gentype == wordgen && outcol < 58) {
  293.                 fprintf(output,",%d",val & 0x0ffff);
  294.                 outcol += 6;
  295.                 }
  296.         else    {
  297.                 nl();
  298.                 fprintf(output,"\tDC.W\t%d",val & 0x0ffff);
  299.                 gentype = wordgen;
  300.                 outcol = 21;
  301.                 }
  302.         return 2;                       /* 2 bytes generated */
  303. }
  304.  
  305. int  genlong(val)
  306. int     val;
  307. {       if( gentype == longgen && outcol < 56) {
  308.                 fprintf(output,",%d",val);
  309.                 outcol += 10;
  310.                 }
  311.         else    {
  312.                 nl();
  313.                 fprintf(output,"\tDC.L\t%d",val);
  314.                 gentype = longgen;
  315.                 outcol = 25;
  316.                 }
  317.        return 4;                        /* generates 4 bytes    */
  318. }
  319.  
  320.  genref(sp,offset)
  321. SYM     *sp;
  322. int     offset;
  323. {       char    sign;
  324.         if( offset < 0) {
  325.                 sign = '-';
  326.                 offset = -offset;
  327.                 }
  328.         else
  329.                 sign = '+';
  330.         if( gentype == longgen && outcol < 55 - strlen(sp->name)) {
  331.                 if( sp->storage_class == sc_static)
  332.             fprintf(output,",L_%d%c%d",sp->value.i,sign,offset);
  333.                 else
  334.                         fprintf(output,",%s%c%d",sp->name,sign,offset);
  335.                 outcol += (11 + strlen(sp->name));
  336.                 }
  337.         else    {
  338.                 nl();
  339.                 if(sp->storage_class == sc_static)
  340.             fprintf(output,"\tlong\tL_%d%c%d",sp->value.i,sign,offset);
  341.                 else
  342.                     fprintf(output,"\tlong\t%s%c%d",sp->name,sign,offset);
  343.                 outcol = 26 + strlen(sp->name);
  344.                 gentype = longgen;
  345.                 }
  346. }
  347.  
  348.  genstorage(nbytes)
  349. int     nbytes;
  350. {       nl();
  351.         fprintf(output,"\tDS.B\t%d\n",nbytes);
  352. }
  353.  
  354.  gen_labref(n)
  355. int     n;
  356. {       if( gentype == longgen && outcol < 58) {
  357.         fprintf(output,",L_%d",n);
  358.                 outcol += 6;
  359.                 }
  360.         else    {
  361.                 nl();
  362.         fprintf(output,"\tlong\tL_%d",n);
  363.                 outcol = 22;
  364.                 gentype = longgen;
  365.                 }
  366. }
  367.  
  368. int     stringlit(s)
  369. /*
  370.  *      make s a string literal and return it's label number.
  371.  */
  372. char    *s;
  373. {       struct slit     *lp;
  374.         ++global_flag;          /* always allocate from global space. */
  375.         lp = (struct slit *)xalloc(sizeof(struct slit));
  376.         lp->label = nextlabel++;
  377.         lp->str =(char *) litlate(s);
  378.         lp->next = strtab;
  379.         strtab = lp;
  380.         --global_flag;
  381.         return lp->label;
  382. }
  383.  
  384.  dumplits()
  385. /*
  386.  *      dump the string literal pool.
  387.  */
  388. {       char            *cp;
  389.         while( strtab != 0) {
  390.                 cseg();
  391.                 nl();
  392.                 put_label(strtab->label);
  393.                 cp = strtab->str;
  394.                 while(*cp)
  395.                         genbyte(*cp++);
  396.                 genbyte(0);
  397.                 strtab = strtab->next;
  398.                 }
  399.         nl();
  400. }
  401.  
  402.  nl()
  403. {       if(outcol > 0) {
  404.                 fprintf(output,"\n");
  405.                 outcol = 0;
  406.                 gentype = nogen;
  407.                 }
  408. }
  409.  
  410.  cseg()
  411. {       if( curseg != codeseg) {
  412.                 nl();
  413.                 fprintf(output,"\tSECTION\t9\n");
  414.                 curseg = codeseg;
  415.                 }
  416. }
  417.  
  418.  dseg()
  419. {       if( curseg != dataseg) {
  420.                 nl();
  421.                 fprintf(output,"\tSECTION\t15\n");
  422.                 curseg = dataseg;
  423.                 }
  424. }
  425.  upcase(stg)                /* Convert string to upper case */
  426. char stg[];
  427. {
  428.   int i;
  429.  
  430.   i=0;
  431.   while(stg[i])
  432.   {
  433.     stg[i]=toupper(stg[i]);
  434.     i++;
  435.   }
  436. }
  437.  
  438.